/*******************************************************************************
 * Copyright (c) 2009 Markus Knittig and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Markus Knittig - initial API and implementation
 *******************************************************************************/
package com.googlecode.mylyn.core.util;

import java.nio.ByteBuffer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.annotation.CheckForNull;

public class GoogleCodeUtils {
    
    /**
     * The Google Code project domain prefix string, optionally https.
     */
    private static final String PREFIX = "https?://code\\.google\\.com/";
    
    private static final String AFFILIATION = "a/[a-zA-Z_0-9\\-\\.]+";
    
    private static final String HOSTING = "/?p/";
    
    private static final String PROJECT_ID = "[a-zA-Z_0-9\\-]+";
    
    private static final String OPTIONAL_SLASH = "/?";
    
    /**
     * Regular expression to extract the project id from the project URL.
     * <ol>
     * <li>prefix URL</li>
     * <li>porject id</li> 
     * <li>optional slach</li>
     * </ol>
     */
    private static final Pattern PROJECT_PATTERN = Pattern.compile("(" + PREFIX + ")(" + AFFILIATION + ")?(" + HOSTING + ")(" + PROJECT_ID + ")(" + OPTIONAL_SLASH + ")");
    
    /**
     * Index of the regex group in {@link #PROJECT_PATTERN} that contains the project id.
     */
    private static final int PROJECT_ID_GROUP = 4;

    /**
     * Index of the regex group in {@link #PROJECT_PATTERN} that contains the project id.
     */
    private static final int AFFILIATION_ID_GROUP = 2;
    
    public static boolean hasNonAsciiCharacters(String text) {
        CharsetDecoder decoder = Charset.forName("US-ASCII").newDecoder();
        try {
            decoder.decode(ByteBuffer.wrap(text.getBytes()));
        } catch (CharacterCodingException e) {
            return true;
        }
        return false;
    }
    
    /**
     * Extract the project id from the repository URL
     * 
     * @param repositoryUrl the repository URL, eg. {@literal "http://code.google.com/p/googlecode-mylyn-connector/"}
     * @return the project id or {@literal null} if no project id could be extracted
     */
    @CheckForNull
    public static String extractProjectId(String repositoryUrl) {
        Matcher matcher = PROJECT_PATTERN.matcher(repositoryUrl);
        if (matcher.matches()) {
            return matcher.group(PROJECT_ID_GROUP).trim();
        } else {
            return null;
        }
    }

    /**
     * Extract the project id from the repository URL
     * 
     * @param repositoryUrl the repository URL, eg. {@literal "http://code.google.com/p/googlecode-mylyn-connector/"}
     * @return the project id or {@literal null} if no project id could be extracted
     */
    @CheckForNull
    public static String extractProjectAffiliation(String repositoryUrl) {
        Matcher matcher = PROJECT_PATTERN.matcher(repositoryUrl);
        if (matcher.matches()) {
            String group = matcher.group(AFFILIATION_ID_GROUP);
            return group == null ? "" : group.trim() + "/";
        } else {
            return "";
        }
    }
    
    @CheckForNull
    public static String getRepositoryFeedUrl(String repositoryUrl) {
        String projectAffiliation = GoogleCodeUtils.extractProjectAffiliation(repositoryUrl);
        return "http://code.google.com/"
               + projectAffiliation
               + "feeds/issues/p/"
               + GoogleCodeUtils.extractProjectId(repositoryUrl);
    }
}
